﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using chromium.Utils;

namespace chromium.HTTP.Parser
{
    public class HttpResponse
    {
        private readonly List<string> cookies = new List<string>();
        private readonly List<HttpHeader> headers = new List<HttpHeader>();
        private readonly Stream clientStream;
        private bool headerRendered;

        public HttpResponse(Stream clientStream)
        {
            this.clientStream = clientStream;
        }

        public int Status { get; set; }

        public int ContentLength { get; set; }

        public void AddCookie(string cookie)
        {
            cookies.Add(cookie);
        }

        public void AddHeader(string header, string value)
        {
            headers.Add(new HttpHeader(header, value));
        }

        public void Write(byte[] content, int start, int length)
        {
            if (!headerRendered)
            {
                RenderHeader(clientStream, false);
            }
            clientStream.Write(content, start, length);
        }

        public void SendCache(byte[] content)
        {
            clientStream.Write(content, 0, content.Length);
        }

        public void Abort()
        {
            clientStream.Close();
            clientStream.Dispose();
        }

        public void Close()
        {
            if (!headerRendered)
            {
                RenderHeader(clientStream, false);
            }

            clientStream.Flush();
        }

        private void RenderHeader(Stream stream, bool fromCache)
        {
            var sb = new StringBuilder();
            sb.AppendFormat("HTTP/1.1 {0} OK\r\n", Status);
            foreach (HttpHeader httpHeader in headers)
            {
                sb.AppendFormat("{0}: {1}\r\n", httpHeader.Name, httpHeader.Value);
            }
            foreach (string cooky in cookies)
            {
                sb.AppendFormat("{0}: {1}\r\n", "set-cookie", cooky);
            }
            sb.AppendFormat("{0}: {1}\r\n", "content-length", ContentLength);
            sb.AppendFormat("{0}: {1}\r\n", "date", DateTime.Now.ToString("R"));
            if (fromCache)
                sb.AppendFormat("X-CA: 200 Hit from Memory Cache\r\n");
            sb.AppendFormat("\r\n");
            byte[] content = Encoding.ASCII.GetBytes(sb.ToString());
            stream.Write(content, 0, content.Length);
            headerRendered = true;
        }

        public void Send304()
        {
            clientStream.Write(Resources.Instance.Http304Bytes, 0, Resources.Instance.Http304Bytes.Length);
        }
    }
}